package com.zhiyu.service.impl;

import com.zhiyu.common.RoleType;
import com.zhiyu.entity.DO.AccountDO;
import com.zhiyu.entity.DO.UserDO;
import com.zhiyu.entity.VO.LoginFormVO;
import com.zhiyu.entity.VO.RegisterFormVO;
import com.zhiyu.entity.VO.ResponseVO;
import com.zhiyu.service.*;
import com.zhiyu.util.JWTUtil;
import com.zhiyu.util.MapBuilder;
import com.zhiyu.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.Map;

@Service
public class IndexServiceImpl implements IndexService {

    @Autowired
    private AccountService accountService;

    @Autowired
    private EncryptService encryptService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserService userService;

    @Autowired
    private ResponseUtil responseUtil;

    @Autowired
    private JWTUtil jwtUtil;

    @Override
    public ResponseVO login(LoginFormVO loginFormVO) {
        String username = loginFormVO.getUsername();
        AccountDO accountDO = accountService.findByUsername(username);
        if (accountDO == null)  //账号不存在
            return responseUtil.loginFail();

        String truePassword = accountDO.getPassword();
        String encryptedPassword = loginFormVO.getPassword();

        String redisField = encryptService.getPrivateKeyField() + loginFormVO.getUsername();
        String privateKey = redisService.getKey(redisField);    //从redis中取出私钥

        if(privateKey == null)  //找不到私钥
            return responseUtil.loginFail();

        if (encryptService.verify(encryptedPassword, truePassword, privateKey)) {
            UserDO userDO = userService.findByAccountId(accountDO.getId());

            ResponseVO responseVO = responseUtil.success();
            String jwtToken = generateJWTToken(String.valueOf(userDO.getId()));
            Map map = MapBuilder.newInstance().put("id", userDO.getId()).put("token", jwtToken).build();
            responseVO.setData(map);

            return responseVO;
        } else {    //密码错误
            return responseUtil.loginFail();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseVO register(RegisterFormVO registerFormVO) {
        String username = registerFormVO.getUsername();
        if(accountService.checkAccount(username))
            return responseUtil.accountExisited();

        String redisField = encryptService.getPrivateKeyField() + registerFormVO.getUsername();
        String privateKey = redisService.getKey(redisField);    //从redis中取出私钥

        if(privateKey == null)
            return responseUtil.registerFail();

        String password = encryptService.RSADecrypt(registerFormVO.getPassword(), privateKey);

        try {
            //添加账号
            AccountDO newAccountDO = accountService.addNewAccount(username, password);

            //为账号关联一个用户
            UserDO userDO = userService.addNewUser(newAccountDO.getId());

            //为用户关联角色
            roleService.addRole(userDO.getId(), RoleType.NORMAL);

            ResponseVO responseVO = responseUtil.success();

            //注册成功后默认为登陆，所以要返回token
            String jwtToken = generateJWTToken(String.valueOf(userDO.getId()));
            Map map = MapBuilder.newInstance().put("id", userDO.getId()).put("token", jwtToken).build();
            responseVO.setData(map);

            return responseVO;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return responseUtil.registerFail();
        }
    }

    /**
     * 生成jwt
     *
     * @param subject 主题
     * @return jwt
     */
    private String generateJWTToken(String subject) {
        return jwtUtil.createToken(String.valueOf(subject));
    }


}
